package mop.gui.main;

import java.beans.PropertyChangeEvent;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JPanel;

import mop.gui.GUI;
import mop.gui.project.*;
import mop.gui.resource.*;
import mop.gui.task.*;

import mop.controller.AssignTaskToProjectController;
import mop.controller.ChangeClockController;
import mop.controller.ControllerVisitor;
import mop.controller.CreateProjectController;
import mop.controller.CreateResourceController;
import mop.controller.CreateTaskController;
import mop.controller.CreateUserController;
import mop.controller.FocusWorkController;
import mop.controller.LoginUserController;
import mop.controller.MakeResourceReservationController;
import mop.controller.ModifyTaskDetailsController;
import mop.controller.RemoveProjectController;
import mop.controller.RemoveTaskController;
import mop.controller.UpdateTaskStatusController;
import mop.controller.UseCaseController;

/**
 * MainWindow
 * 
 * @author  Laurens
 */
public class MainWindow extends javax.swing.JFrame implements ControllerVisitor
{    
    /**
     * Constructor.
     * 
     * @param   gui
     * @param   controllers
     * @effect  Sets the gui object.
     * @effect  Initialises panel list.
     * @effect  Visits the controllers.
     * @effect  Updates all panels.
     */
    public MainWindow(GUI gui, List<UseCaseController> controllers)
    {
        initComponents();
        setGui(gui);

        // Panels
        this.panels = new LinkedList<MainPanelInterface>();

        // Visit controllers
        for (UseCaseController ucc : controllers)
    	{
    		ucc.visit(this);
    	}

        // Update everything
        this.update();
    }
    
    /***************************************************************************
     *                          GUI reference
     ***************************************************************************/
    
    private GUI gui;
    
    /**
     * Sets the GUI.
     * 
     * @param   gui
     * @post    gui is set.
     */
    private void setGui(GUI gui)
    {
        this.gui = gui;
    }
    
    /**
     * Returns the GUI reference.
     * 
     * @return  this.gui
     */
    public GUI getGui()
    {
        return this.gui;
    }

    /***************************************************************************
     *                          Window-specific functionality
     ***************************************************************************/

    private List<MainPanelInterface> panels;

    /**
     * Updates all tables in MainWindow.
     */
    public void update()
    {
        // Show current user.
        String currentUser = loginUserController.getCurrentUser().getId();
        this.lblCurrentUser.setText("Current User: " + currentUser);

        // Update panels.
        for (MainPanelInterface p : this.panels)
            p.update();
    }
    
    /***************************************************************************
     *                          Controllers
     ***************************************************************************/
    
    private AssignTaskToProjectController assignTaskToProjectController;
    private ChangeClockController changeClockController;
    private CreateProjectController createProjectController;
    private CreateResourceController createResourceController;
    private CreateTaskController createTaskController;
    private CreateUserController createUserController;
    private FocusWorkController focusWorkController;
    private LoginUserController loginUserController;
    private MakeResourceReservationController makeResourceReservationController;
    private ModifyTaskDetailsController modifyTaskDetailsController;
    private RemoveProjectController removeProjectController;
    private RemoveTaskController removeTaskController;
    private UpdateTaskStatusController updateTaskStatusController;

    @Override
    public void action(AssignTaskToProjectController c)
    {
            this.assignTaskToProjectController = c;
    }

    @Override
    public void action(ChangeClockController c)
    {
            this.changeClockController = c;
    }

    @Override
    public void action(CreateProjectController c)
    {
            this.createProjectController = c;
    }

    @Override
    public void action(CreateResourceController c)
    {
            this.createResourceController = c;
            MainPanelInterface panel = new ResourcePanel(gui, c);
            this.panels.add(panel);
            this.mainPane.add((JPanel)panel);
    }

    @Override
    public void action(CreateTaskController c)
    {
            this.createTaskController = c;
    }

    @Override
    public void action(CreateUserController c)
    {
            this.createUserController = c;
    }

    @Override
    public void action(FocusWorkController c)
    {
            this.focusWorkController = c;
    }

    @Override
    public void action(MakeResourceReservationController c)
    {
            this.makeResourceReservationController = c;
    }

    @Override
    public void action(ModifyTaskDetailsController c)
    {
            this.modifyTaskDetailsController = c;
    }

    @Override
    public void action(RemoveTaskController c)
    {
            this.removeTaskController = c;
            MainPanelInterface panel = new TaskPanel(gui, c);
            this.panels.add(panel);
            this.mainPane.add((JPanel)panel);
    }

    @Override
    public void action(UpdateTaskStatusController c)
    {
            this.updateTaskStatusController = c;
    }

    @Override
    public void action(LoginUserController c)
    {
            this.loginUserController = c;
    }

    @Override
    public void action(RemoveProjectController c)
    {
            this.removeProjectController = c;
            MainPanelInterface panel = new ProjectPanel(gui, c);
            this.panels.add(panel);
            this.mainPane.add((JPanel)panel);
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        mainPane = new javax.swing.JTabbedPane();
        tabMain = new javax.swing.JPanel();
        lblTitle = new javax.swing.JLabel();
        lblCredits = new javax.swing.JLabel();
        btnLogout = new javax.swing.JButton();
        lblCurrentUser = new javax.swing.JLabel();
        mainMenuBar = new javax.swing.JMenuBar();
        menuFile = new javax.swing.JMenu();
        itemQuit = new javax.swing.JMenuItem();
        menuHelp = new javax.swing.JMenu();
        itemForceUpdate = new javax.swing.JMenuItem();
        javax.swing.JMenu jMenu1 = new javax.swing.JMenu();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("MOP Project"); // NOI18N
        setName("Form"); // NOI18N

        mainPane.setName("mainPane"); // NOI18N

        tabMain.setName("tabMain"); // NOI18N
        tabMain.setLayout(new java.awt.GridBagLayout());

        lblTitle.setFont(new java.awt.Font("Tahoma", 1, 14));
        lblTitle.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblTitle.setText("MOP Project 2009-2010 - Iteratie 3");
        lblTitle.setName("lblTitle"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
        gridBagConstraints.ipady = 40;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.insets = new java.awt.Insets(-25, 4, 0, 4);
        tabMain.add(lblTitle, gridBagConstraints);

        lblCredits.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblCredits.setText("<html> Adriaan Larmuseau<br>  Laurens Van Keer<br> Seba Kerckhof<br> </html>"); // NOI18N
        lblCredits.setName("lblCredits"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.ipadx = 23;
        gridBagConstraints.ipady = 40;
        tabMain.add(lblCredits, gridBagConstraints);

        btnLogout.setText("Log Out");
        btnLogout.setName("btnLogout"); // NOI18N
        btnLogout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnLogoutActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.ipadx = 70;
        gridBagConstraints.insets = new java.awt.Insets(20, 0, 0, 0);
        tabMain.add(btnLogout, gridBagConstraints);

        mainPane.addTab("Main", tabMain);

        lblCurrentUser.setText("Current User:"); // NOI18N
        lblCurrentUser.setName("lblCurrentUser"); // NOI18N

        mainMenuBar.setName("mainMenuBar"); // NOI18N

        menuFile.setText("File"); // NOI18N
        menuFile.setName("menuFile"); // NOI18N

        itemQuit.setText("Quit"); // NOI18N
        itemQuit.setName("itemQuit"); // NOI18N
        itemQuit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                itemQuitActionPerformed(evt);
            }
        });
        menuFile.add(itemQuit);

        mainMenuBar.add(menuFile);

        menuHelp.setText("Help"); // NOI18N
        menuHelp.setName("menuHelp"); // NOI18N

        itemForceUpdate.setText("Force update tables");
        itemForceUpdate.setName("itemForceUpdate"); // NOI18N
        itemForceUpdate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                itemForceUpdateActionPerformed(evt);
            }
        });
        menuHelp.add(itemForceUpdate);

        mainMenuBar.add(menuHelp);

        jMenu1.setName("jMenu1"); // NOI18N
        mainMenuBar.add(jMenu1);

        setJMenuBar(mainMenuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(lblCurrentUser)
                    .addComponent(mainPane, javax.swing.GroupLayout.DEFAULT_SIZE, 522, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(mainPane, javax.swing.GroupLayout.DEFAULT_SIZE, 597, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(lblCurrentUser)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

/**
 * Opens the "create project" dialog.
 * 
 * @param   evt
 */
/**
 * Forces an update of all tables.
 * 
 * @param   evt
 */
private void itemForceUpdateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_itemForceUpdateActionPerformed
    this.update();
}//GEN-LAST:event_itemForceUpdateActionPerformed

/**
 * Closes the application.
 * @param   evt
 */
private void itemQuitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_itemQuitActionPerformed
    System.exit(0);
}//GEN-LAST:event_itemQuitActionPerformed

/**
 * Opens the "create project" dialog.
 * 
 * @param   evt
 */
/**
 * Updates "focus work" tables.
 * 
 * @param   evt
 */
/**
 * Opens the ChangeClockDialog.
 * 
 * @param   evt
 */
private void btnLogoutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLogoutActionPerformed
    try {
        gui.handleSuccess("Logged out!");
        this.dispose();
    } catch (Throwable exception) {
        gui.handleError(exception);
    }
}//GEN-LAST:event_btnLogoutActionPerformed

/**
 * Handles property change.
 * 
 * @param   e
 */
public void handlePropertyChange(PropertyChangeEvent e)
{
    this.update();
}

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnLogout;
    private javax.swing.JMenuItem itemForceUpdate;
    private javax.swing.JMenuItem itemQuit;
    private javax.swing.JLabel lblCredits;
    private javax.swing.JLabel lblCurrentUser;
    private javax.swing.JLabel lblTitle;
    private javax.swing.JMenuBar mainMenuBar;
    private javax.swing.JTabbedPane mainPane;
    private javax.swing.JMenu menuFile;
    private javax.swing.JMenu menuHelp;
    private javax.swing.JPanel tabMain;
    // End of variables declaration//GEN-END:variables
}